package com.yDev.rockclimber;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Paint.Style;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Gallery;

import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class StickMan extends SurfaceView implements SurfaceHolder.Callback {

	ArrayList<Point> clicked = new ArrayList<Point>();;

	private MainThread thread;

	private Timer myTimer;
	Boolean executeTimer = false;
	Boolean isGameState = true;

	int seconds = 0;
	
	int OFFSETY=0;

	Boolean draw;
	Paint paint;

	BodyPart Head, Torso, RightArm, LeftArm, RightLeg, LeftLeg;
	
	Dialog viewAddRock;
	Gallery myGallery;
	TextView textViewX, textViewY;
	
	Button btnAdd, btnCancel;
	
	
	int selectedGalleryID=R.drawable.rock1;

	Wall mWall = new Wall(getContext());

	Point headPos = new Point();

	final static int TOLERANCE = 20;
	final static double RADIO = 2;
	final static int HEAD_SIZE = 15;
	final static int TORSO_SIZE = 100;
	final static int ARM_SIZE = 50;
	final static int LEG_SIZE = 60;
	
	final static int HEAD_WIDTH = 40;
	final static int HEAD_HEIGHT = 45;
	final static int TORSO_WIDTH = 105;
	final static int TORSO_HEIGHT =161;
	final static int BICEP_WIDTH = 84;
	final static int BICEP_HEIGHT = 28;
	final static int FOREARM_WIDTH = 54;
	final static int FOREARM_HEIGHT =24;
	final static int THIGH_WIDTH = 41;
	final static int THIGH_HEIGHT = 96;
	final static int LEG_WIDTH = 31;
	final static int LEG_HEIGHT =105;
	
	
	Point clickedAt;

	public StickMan(Context context) {
		super(context);
		clickedAt = new Point(130, 500);
		// setWillNotDraw(false);

		// this.setBackgroundColor(Color.WHITE);

		getHolder().addCallback(this);
		setFocusable(true);

		thread = new MainThread(getHolder(), this);

		paint = new Paint();

		init();

		myTimer = new Timer();
		myTimer.schedule(new TimerTask() {
			@Override
			public void run() {
				// TimerMethod();
			}

		}, 0, 1000);

	}

	public void init() {

		paint.setColor(Color.BLACK);
		paint.setStrokeWidth(15);
		paint.setStyle(Style.FILL_AND_STROKE);

		BodyPart.context = getContext();
		BodyPart.paint = paint;

		Head = new BodyPart(R.drawable.stetched_head,R.drawable.stetched_head, HEAD_WIDTH,HEAD_HEIGHT);
		Head.bodyPart = "Head";
		Head.size = HEAD_SIZE * RADIO;

		Torso = new BodyPart(R.drawable.stetched_back, R.drawable.torso_drawn,TORSO_WIDTH, TORSO_HEIGHT);
		Torso.bodyPart = "Torso";
		Torso.size = TORSO_SIZE * RADIO;

		RightArm = new BodyPart(R.drawable.stetched_left_bicep, R.drawable.stetched_left_forearm,
				BICEP_WIDTH, BICEP_HEIGHT, FOREARM_WIDTH, FOREARM_HEIGHT);
		RightArm.bodyPart = "RightArm";
		RightArm.size = ARM_SIZE * RADIO;

		LeftArm = new BodyPart(R.drawable.stetched_right_bicep, R.drawable.stetched_right_forearm,
				BICEP_WIDTH, BICEP_HEIGHT, FOREARM_WIDTH, FOREARM_HEIGHT);
		LeftArm.bodyPart = "LeftArm";
		LeftArm.size = ARM_SIZE * RADIO;

		RightLeg = new BodyPart();
		RightLeg.bodyPart = "RightLeg";
		RightLeg.size = LEG_SIZE * RADIO;

		LeftLeg = new BodyPart();
		LeftLeg.bodyPart = "LeftLeg";
		LeftLeg.size = LEG_SIZE * RADIO;

		Head.position1.x = 200;
		Head.position1.y = 300;

		Torso.updateTorso(Head);
		RightArm.updateRightArm(Torso);
		LeftArm.updateLeftArm(Torso);
		RightLeg.updateRightLeg(Torso);
		LeftLeg.updateLeftLeg(Torso);

		//mWall.loadMap("");
		
		// nWall.generateWall(new Point(700, 700));
		
        viewAddRock = new Dialog(getContext());
        viewAddRock.setContentView(R.layout.rock_adder);
        viewAddRock.getWindow().setBackgroundDrawable(
				new ColorDrawable(android.graphics.Color.TRANSPARENT));
        
        textViewX=(TextView)viewAddRock.findViewById(R.id.textViewX);
        textViewY=(TextView)viewAddRock.findViewById(R.id.textViewY);
        
        btnAdd=(Button)viewAddRock.findViewById(R.id.btnAdd);
        btnCancel=(Button)viewAddRock.findViewById(R.id.btnCancel);
        
        btnAdd.setOnClickListener(new View.OnClickListener() {

			public void onClick(View v) {
				Point p= new Point(clickedAt.x, clickedAt.y-OFFSETY);
				Rock rock=new Rock(50, selectedGalleryID, p);
				mWall.addRock(rock);
				viewAddRock.dismiss();
			}

		});
        
        btnCancel.setOnClickListener(new View.OnClickListener() {

			public void onClick(View v) {
				viewAddRock.dismiss();
			}

		});
        
        myGallery = (Gallery)(viewAddRock.findViewById(R.id.myGallery));

		myGallery.setAdapter(new ImageAdapter(getContext()));
		
		myGallery.setOnItemSelectedListener(new OnItemSelectedListener() {

			public void onItemSelected(AdapterView<?> parent, View v,
					int position, long id) {
			//	mySelection.setText(" selected option: " + position );
				if(position!=0){
				int i= (int) myGallery.getItemIdAtPosition(position);
				selectedGalleryID= (int) myGallery.getItemIdAtPosition(position);
				}
				
			}

			public void onNothingSelected(AdapterView<?> parent) {
				//mySelection.setText("Nothing selected");
				
			}


		});
	}// onCreate

	public class ImageAdapter extends BaseAdapter {
		/** The parent context */
		private Context myContext;
		// Put some images to project-folder: /res/drawable/
		// format: jpg, gif, png, bmp, ...
		private int[] myImageIds = { R.drawable.rock1, R.drawable.rock2,
				       R.drawable.rock3};

		/** Simple Constructor saving the 'parent' context. */
		public ImageAdapter(Context c) {
			this.myContext = c;
		}

		// inherited abstract methods - must be implemented
		// Returns count of images, and individual IDs
		public int getCount() {
			return this.myImageIds.length;
		}

		public Object getItem(int position) {
			return position;
		}

		public long getItemId(int position) {
			return myImageIds[position];
		}
		// Returns a new ImageView to be displayed,
		public View getView(int position, View convertView, 
				ViewGroup parent) {

			// Get a View to display image data 					
			ImageView iv = new ImageView(this.myContext);
			iv.setImageResource(this.myImageIds[position]);

			// Image should be scaled somehow
			//iv.setScaleType(ImageView.ScaleType.CENTER);
			//iv.setScaleType(ImageView.ScaleType.CENTER_CROP);			
			//iv.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
			//iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
			//iv.setScaleType(ImageView.ScaleType.FIT_XY);
			iv.setScaleType(ImageView.ScaleType.FIT_END);
			
			// Set the Width & Height of the individual images
			iv.setLayoutParams(new Gallery.LayoutParams(95, 70));

			return iv;
		}
	}// ImageAdapter
			

	Matrix mat = new Matrix();
	Matrix mat2 = new Matrix();

	@Override
	protected void onDraw(Canvas canvas) {

		super.onDraw(canvas);

		if (canvas == null) {
			return;
		}

		canvas.drawColor(Color.WHITE);

		mWall.draw(canvas, getContext(), OFFSETY);
		
		Point newPoint = new Point();
		Point oldPoint = new Point();
		if(clicked.size()>=2){
		 for(int i=1; i<clicked.size(); i++){ 
			 
			 newPoint=new Point();
			 oldPoint=new Point();
			 oldPoint=clicked.get(i-1);
		  newPoint=clicked.get(i);
		  canvas.drawLine(oldPoint.x, oldPoint.y, newPoint.x, newPoint.y, paint);
		  //canvas.drawPoint(newPoint.x, newPoint.y, paint);
		  }
		}
		 
		 
		/* if(selectedFromGallery!=null){
			 canvas.drawBitmap(selectedFromGallery, mat, paint);
		 }*/

		paint.setColor(Color.BLUE);
		/*canvas.drawCircle(Head.position1.x, Head.position1.y,
				(float) Head.size, paint);*/

		paint.setColor(Color.BLACK);
		paint.setStrokeWidth(15);
		paint.setStyle(Style.FILL_AND_STROKE);
		
		Head.draw(canvas, false);
		Torso.draw(canvas, false);

		/*canvas.drawLine(Torso.position1.x, Torso.position1.y,
				Torso.position2.x, Torso.position2.y, paint);*/

		/*Bitmap bMapScaled = Bitmap.createScaledBitmap(Torso.mainBitmap, 150,
				(int) Torso.size, true);*/
		// canvas.drawBitmap(bMapScaled, Torso.position1.x-75,
		// Torso.position1.y, paint);

		RightArm.draw(canvas, true);
		LeftArm.draw(canvas, true);
		//LeftArm.drawParameters(canvas);

		/*
		 * canvas.drawLine(LeftArm.position1.x, LeftArm.position1.y,
		 * LeftArm.position2.x, LeftArm.position2.y, paint);
		 * canvas.drawLine(LeftArm.position2.x, LeftArm.position2.y,
		 * LeftArm.position3.x, LeftArm.position3.y, paint);
		 */

		canvas.drawLine(RightLeg.position1.x, RightLeg.position1.y,
				RightLeg.position2.x, RightLeg.position2.y, paint);
		canvas.drawLine(RightLeg.position2.x, RightLeg.position2.y,
				RightLeg.position3.x, RightLeg.position3.y, paint);

		canvas.drawLine(LeftLeg.position1.x, LeftLeg.position1.y,
				LeftLeg.position2.x, LeftLeg.position2.y, paint);
		canvas.drawLine(LeftLeg.position2.x, LeftLeg.position2.y,
				LeftLeg.position3.x, LeftLeg.position3.y, paint);

		canvas.drawPoint(RightArm.position1.x, RightArm.position1.y, paint);

		canvas.drawPoint(clickedAt.x, clickedAt.y, paint);

		
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		clickedAt = new Point((int) event.getX(), (int) event.getY());

		// clickedAt = new Point(300, 400);
		clicked.add(clickedAt);

		if (isGameState) {
			if ((clickedAt.y > Torso.position1.y && clickedAt.y < Torso.position2.y)
					&& ((clickedAt.x < Torso.position1.x && clickedAt.x > Torso.position1.x
							- TOLERANCE) || (clickedAt.x > Torso.position1.x && clickedAt.x < Torso.position1.x
							+ TOLERANCE))) {
				if ((clickedAt.x < Torso.position1.x && clickedAt.x > Torso.position1.x
						- TOLERANCE)
						|| (clickedAt.x > Torso.position1.x && clickedAt.x < Torso.position1.x
								+ TOLERANCE)) {
					if (!Torso.animate) {
						Torso.animateTorsoTo(clickedAt);
					}
				}

			} else {
				int toRA, toLA, toRL, toLL;
				toRA = (int) Math.hypot(clickedAt.x - RightArm.position3.x,
						clickedAt.y - RightArm.position3.y);
				toLA = (int) Math.hypot(clickedAt.x - LeftArm.position3.x,
						clickedAt.y - LeftArm.position3.y);
				toRL = (int) Math.hypot(clickedAt.x - RightLeg.position3.x,
						clickedAt.y - RightLeg.position3.y);
				toLL = (int) Math.hypot(clickedAt.x - LeftLeg.position3.x,
						clickedAt.y - LeftLeg.position3.y);
				int closest = Math.min(Math.min(toRA, toLA),
						Math.min(toRL, toLL));

				if (toRA == closest) {
					RightArm.animateTo(clickedAt);
				} else if (toLA == closest) {
					LeftArm.animateTo(clickedAt);
				} else if (toRL == closest) {
					RightLeg.animateTo(clickedAt);
				} else if (toLL == closest) {
					LeftLeg.animateTo(clickedAt);
				}
			}
		}
		
		
		else{
			viewAddRock.show();
			textViewX.setText(event.getX()+"X");
			textViewY.setText(event.getY()+"Y");
		}
		Log.d("paint", "Circle is at: " + event.getX() + "," + event.getY());
		return true;
	}

	private void calculateTrajectoryForTorso() {

		double deltaX = 0;
		double deltaY = -1;

		/*
		 * deltaX *= SPEED; deltaY *= SPEED;
		 */

		double newX = Torso.position1.x, newY = Torso.position1.y;

		int i = 1;
		/* toCoordinatesTorso.add(0, Torso.position1); */
		Point next = new Point();

		Boolean hypoRA = Math.hypot(
				RightArm.position1.x - RightArm.position3.x,
				RightArm.position1.y - RightArm.position3.y) <= RightArm.size
				* 2 - TOLERANCE;
		Boolean hypoLA = Math.hypot(LeftArm.position1.x - LeftArm.position3.x,
				LeftArm.position1.y - LeftArm.position3.y) <= LeftArm.size * 2
				- TOLERANCE;
		Boolean hypoRL = Math.hypot(
				RightLeg.position1.x - RightLeg.position3.x,
				RightLeg.position1.y - RightLeg.position3.y) <= RightLeg.size
				* 2 - TOLERANCE;
		Boolean hypoLL = Math.hypot(LeftLeg.position1.x - LeftLeg.position3.x,
				LeftLeg.position1.y - LeftLeg.position3.y) <= LeftLeg.size * 2
				- TOLERANCE;

		// while (hypoRA && hypoLA && hypoRL && hypoLL && i<200) {
		// while (Torso.position1.y)
		// if(Torso.position1.y!=)
		next = new Point();
		newX += deltaX;
		newY += deltaY;

		next.x = (int) newX;
		next.y = (int) newY;
		Torso.position1 = next;
		/* toCoordinatesTorso.add(i, next); */
		i++;

		hypoRA = Math.hypot(RightArm.position1.x - RightArm.position3.x,
				RightArm.position1.y - RightArm.position3.y) <= RightArm.size
				* 2 - TOLERANCE;
		hypoLA = Math.hypot(LeftArm.position1.x - LeftArm.position3.x,
				LeftArm.position1.y - LeftArm.position3.y) <= LeftArm.size * 2
				- TOLERANCE;
		hypoRL = Math.hypot(RightLeg.position1.x - RightLeg.position3.x,
				RightLeg.position1.y - RightLeg.position3.y) <= RightLeg.size
				* 2 - TOLERANCE;
		hypoLL = Math.hypot(LeftLeg.position1.x - LeftLeg.position3.x,
				LeftLeg.position1.y - LeftLeg.position3.y) <= LeftLeg.size * 2
				- TOLERANCE;

		// }
	}

	public void calculateTrajectory(ArrayList<Point> to, Point start,
			Point end, int size) {
		// to=new ArrayList<Point>();

		/*
		 * double hypo = Math.hypot(start.x - end.x, start.y - end.y);
		 * 
		 * double deltaX = (end.x - start.x) / hypo; double deltaY = (end.y -
		 * start.y) / hypo;
		 * 
		 * double minDelta = Math.min(Math.abs(deltaX), Math.abs(deltaY));
		 * 
		 * 
		 * deltaX /= minDelta; deltaY /= minDelta;
		 * 
		 * 
		 * deltaX *= SPEED; deltaY *= SPEED;
		 * 
		 * double newX = start.x, newY = start.y;
		 * 
		 * int i = 1; to.add(0, start); Point next = new Point(); hypo = 0;
		 * while (to.get(i - 1).x != end.x && to.get(i - 1).y != end.y && (hypo
		 * < size * 2)) { next = new Point(); newX += deltaX; newY += deltaY;
		 * 
		 * hypo = Math.hypot(start.x - newX, start.y - newY);
		 * 
		 * next.x = (int) newX; next.y = (int) newY; //to.add(i, next); i++; }
		 * executeTimer = true;
		 */
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	public void surfaceCreated(SurfaceHolder holder) {
		thread.setRunning(true);
		thread.start();
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		boolean retry = true;
		while (retry) {
			try {
				thread.join();
				retry = false;
			} catch (InterruptedException e) {
				// try again shutting down the thread
			}
		}
	}

	public void update() {

		Torso.moveTorsoUp(Head, RightArm, LeftArm, RightLeg, LeftLeg);
		RightArm.nextPosition();
		LeftArm.nextPosition();
		RightLeg.nextPosition();
		LeftLeg.nextPosition();
		
		if(Head.position1.y-Head.size-50<0){
			OFFSETY+=5;
			
			Head.offsetBodyPart(OFFSETY);
			Torso.offsetBodyPart(OFFSETY);
			RightArm.offsetBodyPart(OFFSETY);
			LeftArm.offsetBodyPart(OFFSETY);
			RightLeg.offsetBodyPart(OFFSETY);
			LeftLeg.offsetBodyPart(OFFSETY);
			
		}
	}

	public void render(Canvas canvas) {
		/*
		 * if(canvas==null){ return; }
		 * 
		 * canvas.drawColor(Color.WHITE);
		 * 
		 * paint.setColor(Color.BLACK); paint.setStrokeWidth(20); Point
		 * newPoint=new Point(); for(int i=0; i<clicked.size(); i++){
		 * newPoint=new Point(); newPoint=clicked.get(i);
		 * canvas.drawPoint(newPoint.x, newPoint.y, paint); }
		 * 
		 * 
		 * paint.setColor(Color.BLUE); canvas.drawCircle(Head.position1.x,
		 * Head.position1.y, (float) Head.size, paint);
		 * 
		 * paint.setStrokeWidth(5);
		 * 
		 * canvas.drawLine(Torso.position1.x, Torso.position1.y,
		 * Torso.position2.x, Torso.position2.y, paint);
		 * 
		 * canvas.drawLine(RightArm.position1.x, RightArm.position1.y,
		 * RightArm.position2.x, RightArm.position2.y, paint);
		 * canvas.drawLine(RightArm.position2.x, RightArm.position2.y,
		 * RightArm.position3.x, RightArm.position3.y, paint);
		 * 
		 * canvas.drawLine(LeftArm.position1.x, LeftArm.position1.y,
		 * LeftArm.position2.x, LeftArm.position2.y, paint);
		 * canvas.drawLine(LeftArm.position2.x, LeftArm.position2.y,
		 * LeftArm.position3.x, LeftArm.position3.y, paint);
		 * 
		 * canvas.drawLine(RightLeg.position1.x, RightLeg.position1.y,
		 * RightLeg.position2.x, RightLeg.position2.y, paint);
		 * canvas.drawLine(RightLeg.position2.x, RightLeg.position2.y,
		 * RightLeg.position3.x, RightLeg.position3.y, paint);
		 * 
		 * canvas.drawLine(LeftLeg.position1.x, LeftLeg.position1.y,
		 * LeftLeg.position2.x, LeftLeg.position2.y, paint);
		 * canvas.drawLine(LeftLeg.position2.x, LeftLeg.position2.y,
		 * LeftLeg.position3.x, LeftLeg.position3.y, paint);
		 * 
		 * canvas.drawPoint(clickedAt.x, clickedAt.y, paint);
		 * 
		 * nWall.draw(canvas);
		 */

	}

	public void setGameState(Boolean isGameState) {
		this.isGameState = isGameState;
	}

	public void saveMap(String string) {
		mWall.saveMap(string);
		
	}

}
